package com.ikingtech.platform.service.system.user.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ikingtech.framework.sdk.component.api.CompDepartmentApi;
import com.ikingtech.framework.sdk.component.api.CompUserApi;
import com.ikingtech.framework.sdk.component.model.ComponentDepartment;
import com.ikingtech.framework.sdk.component.model.ComponentPost;
import com.ikingtech.framework.sdk.component.model.ComponentUser;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.enums.common.ElementTypeEnum;
import com.ikingtech.framework.sdk.user.model.UserDTO;
import com.ikingtech.framework.sdk.user.model.UserDeptDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.platform.service.system.user.entity.UserDO;
import com.ikingtech.platform.service.system.user.entity.UserDeptDO;
import com.ikingtech.platform.service.system.user.entity.UserTenantDO;
import com.ikingtech.platform.service.system.user.service.repository.ModelConverter;
import com.ikingtech.platform.service.system.user.service.repository.UserDeptRepository;
import com.ikingtech.platform.service.system.user.service.repository.UserRepository;
import com.ikingtech.platform.service.system.user.service.repository.UserTenantRepository;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
 * @author tie yan
 */
@RequiredArgsConstructor
public abstract class AbstractCompUserService implements CompUserApi {

    private final UserRepository service;

    private final UserDeptRepository userDeptRepo;

    private final UserTenantRepository userTenantRepo;

    private final CompDepartmentApi departmentApi;

    private final ModelConverter converter;

    @Override
    public List<ComponentUser> listByIdsAndName(List<String> ids, String name) {
        return this.convert(
                this.converter.modelBatchConvert(
                        this.service.list(Wrappers.<UserDO>lambdaQuery()
                                .in(Tools.Coll.isNotBlank(ids), UserDO::getId, ids)
                                .like(Tools.Str.isNotBlank(name), UserDO::getName, name))
                )
        );
    }

    @Override
    public List<ComponentUser> listByDeptId(String deptId) {
        List<String> userIds = this.userDeptRepo.listObjs(Wrappers.<UserDeptDO>lambdaQuery()
                .select(UserDeptDO::getUserId)
                .eq(UserDeptDO::getDeptId, deptId), String.class::cast);
        if (Tools.Coll.isBlank(userIds)) {
            return new ArrayList<>();
        }
        userIds = this.userTenantRepo.listObjs(Wrappers.<UserTenantDO>lambdaQuery()
                .select(UserTenantDO::getUserId)
                .in(UserTenantDO::getUserId, userIds)
                .eq(UserTenantDO::getTenantCode, Me.tenantCode()), String.class::cast);
        if (Tools.Coll.isBlank(userIds)) {
            return new ArrayList<>();
        }
        return this.convert(this.converter.modelBatchConvert(this.service.listByIds(userIds)));
    }

    private List<ComponentUser> convert(List<UserDTO> users) {
        return Tools.Coll.convertList(users, user -> {
            ComponentUser compUser = new ComponentUser();
            compUser.setElementId(user.getId());
            compUser.setElementName(user.getName());
            compUser.setElementType(ElementTypeEnum.USER);
            compUser.setAvatar(user.getAvatar());
            compUser.setPosts(Tools.Coll.convertList(user.getPosts(), post -> {
                ComponentPost compPost = new ComponentPost();
                compPost.setElementId(post.getPostId());
                compPost.setElementName(post.getPostName());
                compPost.setElementType(ElementTypeEnum.POST);
                return compPost;
            }));
            compUser.setDepartments(Tools.Coll.convertList(user.getDepartments(), department -> {
                ComponentDepartment compDepartment = this.convertDepartment(department);
                if (null != department.getUnity()) {
                    compDepartment.setUnity(this.convertDepartment(department.getUnity()));
                }
                return compDepartment;
            }));
            compUser.setDepartmentFullNames(new ArrayList<>(this.departmentApi.extractDepartmentFullName(Tools.Coll.convertMap(user.getDepartments(), UserDeptDTO::getDeptId, UserDeptDTO::getDeptFullPath)).values()));
            return compUser;
        });
    }

    private ComponentDepartment convertDepartment(UserDeptDTO department) {
        ComponentDepartment compDepartment = new ComponentDepartment();
        compDepartment.setElementId(department.getDeptId());
        compDepartment.setElementName(department.getDeptName());
        compDepartment.setElementType(ElementTypeEnum.DEPT);
        compDepartment.setDeptType(department.getDeptType());
        if (null != compDepartment.getDeptType()) {
            compDepartment.setDeptTypeName(compDepartment.getDeptType().description);
        }
        return compDepartment;
    }
}
